From a129d4b5f6044b5ac75a58cbb2ec355562789219 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 22 Jan 2008 17:18:51 +0000 Subject: [PATCH] vmx realmode: Faster emulation of REP INS and REP OUTS. This makes, in particular, reading files via the BIOS disk abstraction much much much faster. Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/vmx/realmode.c | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/xen/arch/x86/hvm/vmx/realmode.c b/xen/arch/x86/hvm/vmx/realmode.c index a7f767926e..39b1fdb590 100644 --- a/xen/arch/x86/hvm/vmx/realmode.c +++ b/xen/arch/x86/hvm/vmx/realmode.c @@ -223,6 +223,64 @@ realmode_emulate_cmpxchg( return realmode_emulate_write(seg, offset, new, bytes, ctxt); } +static int +realmode_rep_ins( + uint16_t src_port, + enum x86_segment dst_seg, + unsigned long dst_offset, + unsigned int bytes_per_rep, + unsigned long *reps, + struct x86_emulate_ctxt *ctxt) +{ + struct realmode_emulate_ctxt *rm_ctxt = + container_of(ctxt, struct realmode_emulate_ctxt, ctxt); + struct vcpu *curr = current; + uint32_t paddr = rm_ctxt->seg_reg[dst_seg].base + dst_offset; + + if ( curr->arch.hvm_vmx.real_mode_io_in_progress ) + return X86EMUL_UNHANDLEABLE; + + if ( !curr->arch.hvm_vmx.real_mode_io_completed ) + { + curr->arch.hvm_vmx.real_mode_io_in_progress = 1; + send_pio_req(src_port, *reps, bytes_per_rep, + paddr, IOREQ_READ, + !!(ctxt->regs->eflags & X86_EFLAGS_DF), 1); + } + + if ( !curr->arch.hvm_vmx.real_mode_io_completed ) + return X86EMUL_RETRY; + + curr->arch.hvm_vmx.real_mode_io_completed = 0; + + return X86EMUL_OKAY; +} + +static int +realmode_rep_outs( + enum x86_segment src_seg, + unsigned long src_offset, + uint16_t dst_port, + unsigned int bytes_per_rep, + unsigned long *reps, + struct x86_emulate_ctxt *ctxt) +{ + struct realmode_emulate_ctxt *rm_ctxt = + container_of(ctxt, struct realmode_emulate_ctxt, ctxt); + struct vcpu *curr = current; + uint32_t paddr = rm_ctxt->seg_reg[src_seg].base + src_offset; + + if ( curr->arch.hvm_vmx.real_mode_io_in_progress ) + return X86EMUL_UNHANDLEABLE; + + curr->arch.hvm_vmx.real_mode_io_in_progress = 1; + send_pio_req(dst_port, *reps, bytes_per_rep, + paddr, IOREQ_WRITE, + !!(ctxt->regs->eflags & X86_EFLAGS_DF), 1); + + return X86EMUL_OKAY; +} + static int realmode_read_segment( enum x86_segment seg, @@ -420,6 +478,8 @@ static struct x86_emulate_ops realmode_emulator_ops = { .insn_fetch = realmode_emulate_insn_fetch, .write = realmode_emulate_write, .cmpxchg = realmode_emulate_cmpxchg, + .rep_ins = realmode_rep_ins, + .rep_outs = realmode_rep_outs, .read_segment = realmode_read_segment, .write_segment = realmode_write_segment, .read_io = realmode_read_io, -- 2.30.2